1. Technical Field
The present invention relates in general to data processing systems and in particular to multiprocessor systems. Still more particularly, the present invention relates to an improved method and system for tracing of execution events in a multiprocessor system.
2. Description of the Related Art
Computer software typically includes a stream of multiple interrelated events. Tentative tracing of software is the ability to collect execution events and to enable one or more execution events to be either discarded or committed as part of an execution trace. Each execution event is typically discarded or committed depending on the occurrence of another event in the future (e.g., when a condition becomes true or false).
In conventional data processing systems, tentative tracing can be intermixed with non-tentative tracing. A stream of events that is collected during a tracing process can thus include a mix of non-tentative events, which will unconditionally be part of the trace, and tentative events, which may or may not end up being part of the trace. Furthermore, conventional data processing systems can include simultaneous “threads” of tentative tracing that are all interleaved in the same stream of events. For each simultaneous thread that is traced tentatively, there is a different set of events and/or conditions that may trigger each event within the thread to be either discarded or committed at a future time (i.e., during execution of the thread).
In conventional multiprocessor systems, tentative events must be stored in one or more buffers in a way that enables the events to be committed or discarded efficiently in the future. Contention among multiple processors must also be minimized in order to enable efficient scaling of the system as the number of processors increases. Conventional multiprocessor systems typically minimize contention by including separate buffers for each processor that store the events generated by a particular processor. However, different processors may generate multiple tentative events for the same tentative thread, thereby causing tentative events of a single thread to be spread across different buffers that belong to different processors. Committing or discarding an event that is spread across different buffers thus requires that multiple buffers be accessed, which may lead to errors unless serialization techniques (e.g. spin lock synchronization) are utilized. Spin lock synchronization requires the execution of atomic memory access instructions every time the spin lock is accessed, thereby increasing the processing time and decreasing the overall efficiency of the multiprocessor system.
Conventional multiprocessor systems may also include separate buffers for tentative and non-tentative events. For example, a single processor system that includes M simultaneous threads of tracing activity would require M+1 different buffers, while a similar multiprocessor system with N processors would require N*(M+1) different buffers. Consequently, the combination of a large buffer size, a large number of tentative threads, and a large number of processors increases memory consumption dramatically as the system is scaled up. In order to commit a tentative event, it is also necessary to merge the buffer corresponding to the tentative event with the non-tentative event buffer in order to ensure that events appear in their original chronological order. Accurately estimating the total capacity of the tentative and non-tentative buffers is also difficult, as some tentative threads may include a high volume of tentative events, while other tentative threads may include a low volume of tentative events.